﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Text.RegularExpressions;
using CalendarParser.ForexNewsServiceReference;
using System.Timers;
using System.Threading;
using System.IO;
namespace CalendarParser
{
    public partial class ForexClockNew : Form
    {
        ForexNewsServiceReference.ForexNewsServiceClient client = new CalendarParser.ForexNewsServiceReference.ForexNewsServiceClient();
        Dictionary<string, DateTime> alarms; //string - Alarm subject, DateTime - alarm time
        string minMsg = "Forex Clock minimized to the tray";
        string notificationTitle = "Forex Alarm";

        public ForexClockNew()
        {
            InitializeComponent();
        }
        
        
        #region Events
        private void btnRefresh_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            RefreshData();
            Cursor.Current = Cursors.Arrow;
        }

        private void ForexClockNew_Load(object sender, EventArgs e)
        {
            RefreshData();
            //MoveFormToTrayOnMinimize();
        }

        private void nicAlarm_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (this.WindowState != FormWindowState.Normal)
            {
                Show();
                this.WindowState = FormWindowState.Normal;
            }
            nicAlarm.Visible = false;
        }

        private void ForexClockNew_Resize(object sender, EventArgs e)
        {
            //On minimize mode, show the form in System Tray only  
            if (FormWindowState.Minimized == WindowState)
            {
                ShowNotification(minMsg);
                Hide();
            }
        }

        private void grdNews_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (e.ColumnIndex == 1)
                {
                    string time = grdNews[2, e.RowIndex].Value.ToString();
                    string news = grdNews[3, e.RowIndex].Value.ToString();

                    AddAlarm(time, news);
                    MessageBox.Show("Alarm is set for " + time + " " + news);
                    grdNews[0, e.RowIndex].Style.ForeColor = Color.Green;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Following Error occured : " + ex.Message);
            }
        }

        private void alarmTimer_Tick(object sender, EventArgs e)
        {
            DateTime now = DateTime.Now;
            string notifications = string.Empty;
            List<string> removeKeys = new List<string>();
            foreach (string news in alarms.Keys)
            {
                if (alarms[news] <= now)
                {
                    notifications = notifications + news + Environment.NewLine;
                    removeKeys.Add(news);
                }
            }
            if (!string.IsNullOrEmpty(notifications))
            {
                ShowNotification(notifications);
                HighLightAlarmRow();
            }

            foreach (string key in removeKeys)
                alarms.Remove(key);

            if (alarms.Count == 0) alarmTimer.Enabled = false;
            SaveAlarmToFile();
        }
        #endregion

        #region Methods

        private void RefreshData()
        {
            lblToday.Text = "Time: " + String.Format("{0:f}", DateTime.Now);

            ShowNewsFromNewsList(client.GetNewsListForToday());
            ShowCityList(client.GetCityListForToday());
            AddAlarm(string.Empty, string.Empty);
        }
        void ShowNewsFromNewsList(List<ForexNews> newslist)
        {

            if (newslist.Count > 0)
            {
                DateTime est;
                foreach (ForexNews news in newslist)
                {   //Covert est to local time before displaying. Dates assumed same
                    est = Convert.ToDateTime(DateTime.Now.ToShortDateString() + " " + news.NewsTime);
                    news.NewsTime = DateTime.Now.AddMinutes(2).ToShortTimeString();// CommonUtility.ConvertESTtoLocalTime(est).ToShortTimeString();
                }
                grdNews.DataSource = newslist;
                lblNoData.Visible = false;
                grdNews.Visible = true;
            }
            else
            {
                lblNoData.Visible = true;
                grdNews.Visible = false;
                //ShowTestData();
            }
        }

        void ShowCityList(List<ForexCity> cities)
        {

            if (cities.Count > 0)
            {
                grdCities.DataSource = cities;
                grdCities.Visible = true;
            }
            else
            {
                grdCities.Visible = false;
            }
        }
        //private void ShowTestData()
        //{
        //    List<ForexNews> newslist = new List<ForexNews>();
        //    ForexNews ForexNews1 = new ForexNews();
        //    ForexNews1.NewsValue = "test news 3 new york";
        //     ForexNews1.NewsTime = DateTime.Now.ToUniversalTime().AddMinutes(4).ToShortTimeString();

        //                ForexNews ForexNews2 = new ForexNews();
        //    ForexNews2.NewsValue = "test news 4 london";
        //     ForexNews2.NewsTime = DateTime.Now.ToUniversalTime().AddMinutes(6).ToShortTimeString();

        //    newslist.Add(ForexNews1);
        //    newslist.Add(ForexNews2);

        //    grdNews.DataSource = newslist;
        //    lblNoData.Visible = false;
        //    grdNews.Visible = true;


        //}


        private void AddAlarm(string time, string news)
        {
            DateTime alarmTime = Convert.ToDateTime(DateTime.Now.ToShortDateString() + " " + time);
            if (alarms == null)
            {
                alarms = new Dictionary<string, DateTime>();//If this is the first alarm create list and add alarm
                ReadAlarmFromFile();
            }
            if (!string.IsNullOrEmpty(news) && !alarms.ContainsKey(news))//Avoid dup alarms
            {
                alarms.Add(news, alarmTime);
                SaveAlarmToFile();
            }
            if (alarms.Count > 0) StartAlarmTimer();
        }

        private void StartAlarmTimer()
        {
            alarmTimer.Interval = 1000;
            alarmTimer.Enabled = true;
        }


        //private void OnAlarmTimer(Object source, ElapsedEventArgs e)
        //{
        //}
        private void ShowNotification(string notifications)
        {

            nicAlarm.Visible = true;
            nicAlarm.Icon = SystemIcons.Information;
            nicAlarm.BalloonTipTitle = notificationTitle;
            nicAlarm.BalloonTipText = notifications;
            nicAlarm.BalloonTipIcon = ToolTipIcon.Info;
            nicAlarm.Text = notificationTitle;
            nicAlarm.ShowBalloonTip(1000);
        }


        private void HighLightAlarmRow()
        {
            if (this.WindowState != FormWindowState.Normal)
            {
                Show();
                this.WindowState = FormWindowState.Normal;
            }
            List<int> alrmRows = new List<int>();
            foreach (DataGridViewRow oItem in grdNews.Rows)
            {
                if (nicAlarm.BalloonTipText.Contains(oItem.Cells[3].Value.ToString()))
                    alrmRows.Add(oItem.Index);
            }

            foreach (int row in alrmRows)
            {
                grdNews.Rows[row].DefaultCellStyle.BackColor = Color.Red;
            }
        }

        void SaveAlarmToFile()
        {
            try
            {

                using (FileStream stream = new FileStream(Application.StartupPath + "\\" + "AlarmData.txt", FileMode.Create))
                using (TextWriter writer = new StreamWriter(stream))
                {
                    foreach (string key in alarms.Keys)
                    {
                        writer.WriteLine(key + "," + alarms[key].ToString());
                    }
                }
            }
            catch (Exception ex)
            {
                //Log error
            }

        }
        void ReadAlarmFromFile()
        {
            try
            {
                using (FileStream stream = new FileStream(Application.StartupPath + "\\" + "AlarmData.txt", FileMode.Open))
                using (TextReader reader = new StreamReader(stream))
                {
                    string input = null;
                    string[] alarmData = null;
                    while ((input = reader.ReadLine()) != null)
                    {
                        alarmData = input.Split(',');
                        alarms.Add(alarmData[0], Convert.ToDateTime(alarmData[1]));
                    }
                }
            }
            catch (Exception ex)
            {
                //Log error
            }

        }

        #endregion

      
    }
}
